import io from 'socket.io-client';
import FingerPrint2 from 'fingerprintjs2';
import config from '@/config';

/**
 * socket工具类
 */
class SocketUtils {

  /**
   * 获取 socket
   * @return {*}
   */
  static getSocket = async () => {
    const serviceUri = await SocketUtils.getServiceUri();
    return io(serviceUri, {
      // 服务器指定的命名空间
      path: config.path,
      // 是否重连接
      reconnection: config.reconnection,
      // 重连接次数
      reconnectionAttempts: config.reconnectionAttempts,
      // 尝试连接前等待时间（单位：秒）
      reconnectionDelay: config.reconnectionDelay,
      // 单次重连最大的等待时间（单位：秒）
      reconnectionDelayMax: config.reconnectionDelayMax,
      // The randomization factor helps smooth
      // the load induced by the reconnection attempts of multiple clients,
      // in case a server goes down
      randomizationFactor: 0.5,
      // 连接服务器的超时时间(默认20秒)
      timeout: config.requestTimeout,
      // socket轮寻方式
      transports: config.transports,
    });
  };

  /**
   * 获取连接地址（带token）
   * @return {string}
   */
  static getServiceUri = async () => {
    const finger = await SocketUtils.getFinger();
    return config.serviceUri
      .concat('?token=', SocketUtils.generateToken(16))
      .concat('&f=', finger.toString());
  };

  static getFinger = () => {
    return new Promise((resolve, reject) => {
      FingerPrint2.get(function(components) {
        const values = components.map(function(component,index) {
          // 把微信浏览器里UA的wifi或4G等网络替换成空,不然切换网络会ID不一样
          if (index === 0) {
            return component.value.replace(/\bNetType\/\w+\b/, '')
          }
          return component.value
        })
        // 浏览器的指纹
        resolve(FingerPrint2.x64hash128(values.join(''), 31));
      })
    })
  }

  static generateToken(len, radix = 10) {
    const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
    const uuid = [];
    let i;
    radix = radix || chars.length;
    if (len) {
      // Compact form
      for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
    } else {
      // rfc4122, version 4 form
      let r;
      // rfc4122 requires these characters
      uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
      uuid[14] = '4';
      // Fill in random data.  At i==19 set the high bits of clock sequence as
      // per rfc4122, sec. 4.1.5
      for (i = 0; i < 36; i++) {
        if (!uuid[i]) {
          r = 0 | Math.random() * 16;
          uuid[i] = chars[(i === 19) ? (r & 0x3) | 0x8 : r];
        }
      }
    }
    return uuid.join('');
  }

}

export default SocketUtils;
